#ifndef REQUEST_H
#define REQUEST_H

#include <QThread>
#include <QHostAddress>
#include "mainwindow.h"

class Request : public QThread
{
    Q_OBJECT

public:
    /* tftp opcode mnemonic */
    enum OpCode
    {
         OC_RRQ = 1,
         OC_WRQ,
         OC_DATA,
         OC_ACK,
         OC_ERROR
    };

    /* tftp transfer mode */
    enum TransMode
    {
         TM_ASCII = 1,
         TM_OCTET
    };

    union Message
    {
         uint16_t opcode;

         struct
         {
              uint16_t opcode; /* OC_RRQ or OC_WRQ */
              char filename_and_mode[514];
         } request;

         struct
         {
              uint16_t opcode; /* OC_DATA */
              uint16_t block_number;
              char data[512];
         } data;

         struct
         {
              uint16_t opcode; /* OC_ACK */
              uint16_t block_number;
         } ack;

         struct
         {
              uint16_t opcode; /* OC_ERROR */
              uint16_t error_code;
              char error_string[512];
         } error;
    };

    explicit Request(MainWindow *window, QString filename, OpCode oc, TransMode tm);

    void run();
    void setRrid(qint32 rrid);
    void setFilePath(QString path);
    void setDestination(const QHostAddress address, quint16 port);

signals:
    void progress(int rowid, qint64 trans, qint64 total);

private:
    int mRrid;
    OpCode mOc;
    TransMode mTm;
    quint16 mPort;
    QString mMode;
    QString mFileName;
    QString mFilePath;
    QHostAddress mAddress;
    MainWindow *mWindow;

    void handleReadReq();
    void handleWriteReq();
};

#endif // REQUEST_H
